@dxos/react-ui-editor 0.8.1 → 0.8.2-main.12df754

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/lib/browser/index.mjs +499 -371
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/testing/index.mjs +67 -0
  5. package/dist/lib/browser/testing/index.mjs.map +7 -0
  6. package/dist/lib/node/index.cjs +515 -379
  7. package/dist/lib/node/index.cjs.map +4 -4
  8. package/dist/lib/node/meta.json +1 -1
  9. package/dist/lib/node/testing/index.cjs +101 -0
  10. package/dist/lib/node/testing/index.cjs.map +7 -0
  11. package/dist/lib/node-esm/index.mjs +499 -371
  12. package/dist/lib/node-esm/index.mjs.map +4 -4
  13. package/dist/lib/node-esm/meta.json +1 -1
  14. package/dist/lib/node-esm/testing/index.mjs +69 -0
  15. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  16. package/dist/types/src/components/EditorToolbar/util.d.ts +3 -3
  17. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  18. package/dist/types/src/components/EditorToolbar/{viewMode.d.ts → view-mode.d.ts} +1 -1
  19. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -0
  20. package/dist/types/src/defaults.d.ts +1 -0
  21. package/dist/types/src/defaults.d.ts.map +1 -1
  22. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  23. package/dist/types/src/extensions/command/action.d.ts +17 -0
  24. package/dist/types/src/extensions/command/action.d.ts.map +1 -0
  25. package/dist/types/src/extensions/command/command.d.ts +5 -10
  26. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  27. package/dist/types/src/extensions/command/hint.d.ts +4 -2
  28. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  29. package/dist/types/src/extensions/command/index.d.ts +1 -0
  30. package/dist/types/src/extensions/command/index.d.ts.map +1 -1
  31. package/dist/types/src/extensions/command/menu.d.ts +7 -2
  32. package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
  33. package/dist/types/src/extensions/command/state.d.ts +9 -11
  34. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  35. package/dist/types/src/extensions/comments.d.ts +9 -7
  36. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  37. package/dist/types/src/extensions/index.d.ts +1 -0
  38. package/dist/types/src/extensions/index.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/decorate.d.ts +4 -1
  40. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  41. package/dist/types/src/extensions/markdown/formatting.d.ts +2 -2
  42. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  43. package/dist/types/src/extensions/markdown/link.d.ts +4 -1
  44. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  45. package/dist/types/src/extensions/preview/index.d.ts +2 -0
  46. package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
  47. package/dist/types/src/extensions/preview/preview.d.ts +39 -0
  48. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
  49. package/dist/types/src/hooks/useTextEditor.d.ts +2 -1
  50. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  51. package/dist/types/src/{InputMode.stories.d.ts → stories/InputMode.stories.d.ts} +1 -1
  52. package/dist/types/src/stories/InputMode.stories.d.ts.map +1 -0
  53. package/dist/types/src/{TextEditor.stories.d.ts → stories/TextEditorBasic.stories.d.ts} +2 -35
  54. package/dist/types/src/stories/TextEditorBasic.stories.d.ts.map +1 -0
  55. package/dist/types/src/stories/TextEditorComments.stories.d.ts +13 -0
  56. package/dist/types/src/stories/TextEditorComments.stories.d.ts.map +1 -0
  57. package/dist/types/src/stories/TextEditorPreview.stories.d.ts +13 -0
  58. package/dist/types/src/stories/TextEditorPreview.stories.d.ts.map +1 -0
  59. package/dist/types/src/stories/TextEditorSpecial.stories.d.ts +19 -0
  60. package/dist/types/src/stories/TextEditorSpecial.stories.d.ts.map +1 -0
  61. package/dist/types/src/stories/story-utils.d.ts +53 -0
  62. package/dist/types/src/stories/story-utils.d.ts.map +1 -0
  63. package/dist/types/src/testing/RefPopover.d.ts +21 -0
  64. package/dist/types/src/testing/RefPopover.d.ts.map +1 -0
  65. package/dist/types/src/testing/index.d.ts +2 -0
  66. package/dist/types/src/testing/index.d.ts.map +1 -0
  67. package/dist/types/src/types.d.ts +5 -0
  68. package/dist/types/src/types.d.ts.map +1 -1
  69. package/dist/types/src/util/react.d.ts +6 -1
  70. package/dist/types/src/util/react.d.ts.map +1 -1
  71. package/package.json +33 -27
  72. package/src/components/EditorToolbar/EditorToolbar.tsx +2 -2
  73. package/src/components/EditorToolbar/util.ts +3 -3
  74. package/src/defaults.ts +5 -3
  75. package/src/extensions/automerge/automerge.stories.tsx +3 -11
  76. package/src/extensions/command/action.ts +49 -0
  77. package/src/extensions/command/command.ts +9 -27
  78. package/src/extensions/command/hint.ts +33 -30
  79. package/src/extensions/command/index.ts +1 -0
  80. package/src/extensions/command/menu.ts +11 -8
  81. package/src/extensions/command/state.ts +41 -61
  82. package/src/extensions/comments.ts +9 -9
  83. package/src/extensions/folding.tsx +1 -1
  84. package/src/extensions/index.ts +1 -0
  85. package/src/extensions/markdown/decorate.ts +4 -3
  86. package/src/extensions/markdown/formatting.ts +2 -2
  87. package/src/extensions/markdown/image.ts +12 -11
  88. package/src/extensions/markdown/link.ts +33 -24
  89. package/src/extensions/preview/index.ts +5 -0
  90. package/src/extensions/preview/preview.ts +271 -0
  91. package/src/hooks/useTextEditor.ts +4 -3
  92. package/src/{InputMode.stories.tsx → stories/InputMode.stories.tsx} +4 -4
  93. package/src/stories/TextEditorBasic.stories.tsx +289 -0
  94. package/src/stories/TextEditorComments.stories.tsx +99 -0
  95. package/src/stories/TextEditorPreview.stories.tsx +239 -0
  96. package/src/stories/TextEditorSpecial.stories.tsx +107 -0
  97. package/src/stories/story-utils.tsx +329 -0
  98. package/src/testing/RefPopover.tsx +74 -0
  99. package/src/testing/index.ts +5 -0
  100. package/src/types.ts +7 -0
  101. package/src/util/react.tsx +20 -2
  102. package/dist/types/src/InputMode.stories.d.ts.map +0 -1
  103. package/dist/types/src/TextEditor.stories.d.ts.map +0 -1
  104. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +0 -1
  105. package/dist/types/src/extensions/command/preview.d.ts +0 -12
  106. package/dist/types/src/extensions/command/preview.d.ts.map +0 -1
  107. package/dist/types/src/fragments.d.ts +0 -3
  108. package/dist/types/src/fragments.d.ts.map +0 -1
  109. package/src/TextEditor.stories.tsx +0 -856
  110. package/src/extensions/command/preview.ts +0 -79
  111. package/src/fragments.ts +0 -19
  112. /package/src/components/EditorToolbar/{viewMode.ts → view-mode.ts} +0 -0
@@ -47,10 +47,10 @@ import { textBlockWidth } from "@dxos/react-ui-theme";
47
47
 
48
48
  // packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
49
49
  import { useMemo } from "react";
50
- import { create } from "@dxos/live-object";
50
+ import { live } from "@dxos/live-object";
51
51
  import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
52
52
  var useEditorToolbarState = (initialState = {}) => {
53
- return useMemo(() => create(initialState), []);
53
+ return useMemo(() => live(initialState), []);
54
54
  };
55
55
  var createEditorAction = (payload, icon, label = [
56
56
  `${payload.type} label`,
@@ -266,7 +266,7 @@ var createLists = (state) => {
266
266
  };
267
267
  };
268
268
 
269
- // packages/ui/react-ui-editor/src/components/EditorToolbar/viewMode.ts
269
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
270
270
  var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
271
271
  variant: "dropdownMenu",
272
272
  applyActive: true,
@@ -311,99 +311,12 @@ var createViewMode = (state) => {
311
311
  };
312
312
  };
313
313
 
314
- // packages/ui/react-ui-editor/src/fragments.ts
315
- import { mx } from "@dxos/react-ui-theme";
316
- var stackItemContentToolbarClassNames = (role) => mx("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
317
-
318
- // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
319
- var createToolbar = ({ state, customActions, ...features }) => {
320
- const nodes = [];
321
- const edges = [];
322
- if (features.headings ?? true) {
323
- const headings2 = createHeadings(state);
324
- nodes.push(...headings2.nodes);
325
- edges.push(...headings2.edges);
326
- }
327
- if (features.formatting ?? true) {
328
- const formatting = createFormatting(state);
329
- nodes.push(...formatting.nodes);
330
- edges.push(...formatting.edges);
331
- }
332
- if (features.lists ?? true) {
333
- const lists = createLists(state);
334
- nodes.push(...lists.nodes);
335
- edges.push(...lists.edges);
336
- }
337
- if (features.blocks ?? true) {
338
- const blocks = createBlocks(state);
339
- nodes.push(...blocks.nodes);
340
- edges.push(...blocks.edges);
341
- }
342
- if (customActions) {
343
- const custom = customActions();
344
- nodes.push(...custom.nodes);
345
- edges.push(...custom.edges);
346
- }
347
- const editorToolbarGap = createGapSeparator();
348
- nodes.push(...editorToolbarGap.nodes);
349
- edges.push(...editorToolbarGap.edges);
350
- if (features.comment ?? true) {
351
- const comment = createComment(state);
352
- nodes.push(...comment.nodes);
353
- edges.push(...comment.edges);
354
- }
355
- if (features.search ?? true) {
356
- nodes.push(editorToolbarSearch);
357
- edges.push({
358
- source: "root",
359
- target: editorToolbarSearch.id
360
- });
361
- }
362
- if (features.viewMode ?? true) {
363
- const viewMode = createViewMode(state);
364
- nodes.push(...viewMode.nodes);
365
- edges.push(...viewMode.edges);
366
- }
367
- return {
368
- nodes,
369
- edges
370
- };
371
- };
372
- var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
373
- const menuCreator = useCallback(() => createToolbar(props), [
374
- props
375
- ]);
376
- const { resolveGroupItems } = useMenuActions(menuCreator);
377
- return {
378
- resolveGroupItems,
379
- onAction
380
- };
381
- };
382
- var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
383
- const menuProps = useEditorToolbarActionGraph(props);
384
- return /* @__PURE__ */ React.createElement("div", {
385
- role: "none",
386
- className: stackItemContentToolbarClassNames(role)
387
- }, /* @__PURE__ */ React.createElement(ElevationProvider, {
388
- elevation: role === "section" ? "positioned" : "base"
389
- }, /* @__PURE__ */ React.createElement(MenuProvider, {
390
- ...menuProps,
391
- attendableId
392
- }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
393
- classNames: [
394
- textBlockWidth,
395
- "!bg-transparent",
396
- classNames
397
- ]
398
- }))));
399
- };
400
-
401
314
  // packages/ui/react-ui-editor/src/defaults.ts
402
315
  import { EditorView } from "@codemirror/view";
403
- import { mx as mx3 } from "@dxos/react-ui-theme";
316
+ import { mx as mx2 } from "@dxos/react-ui-theme";
404
317
 
405
318
  // packages/ui/react-ui-editor/src/styles/markdown.ts
406
- import { mx as mx2 } from "@dxos/react-ui-theme";
319
+ import { mx } from "@dxos/react-ui-theme";
407
320
  var headings = {
408
321
  1: "text-4xl",
409
322
  2: "text-3xl",
@@ -417,7 +330,7 @@ var theme = {
417
330
  codeMark: "font-mono text-primary-500",
418
331
  mark: "opacity-50",
419
332
  heading: (level) => {
420
- return mx2(headings[level], "dark:text-primary-400");
333
+ return mx(headings[level], "dark:text-primary-400");
421
334
  }
422
335
  };
423
336
 
@@ -636,8 +549,9 @@ var defaultTheme = {
636
549
 
637
550
  // packages/ui/react-ui-editor/src/defaults.ts
638
551
  var margin = "!mt-[1rem]";
639
- var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-4rem)]");
640
- var editorFullWidth = mx3(margin);
552
+ var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
553
+ var editorContent = mx2(margin, editorWidth);
554
+ var editorFullWidth = mx2(margin);
641
555
  var editorGutter = EditorView.theme({
642
556
  // Match margin from content.
643
557
  // Gutter = 2rem + 1rem margin.
@@ -652,8 +566,91 @@ var editorMonospace = EditorView.theme({
652
566
  }
653
567
  });
654
568
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
655
- var stackItemContentEditorClassNames = (role) => mx3("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
656
- var stackItemContentToolbarClassNames2 = (role) => mx3("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
569
+ var stackItemContentEditorClassNames = (role) => mx2("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
570
+ var stackItemContentToolbarClassNames = (role) => mx2("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
571
+
572
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
573
+ var createToolbar = ({ state, customActions, ...features }) => {
574
+ const nodes = [];
575
+ const edges = [];
576
+ if (features.headings ?? true) {
577
+ const headings2 = createHeadings(state);
578
+ nodes.push(...headings2.nodes);
579
+ edges.push(...headings2.edges);
580
+ }
581
+ if (features.formatting ?? true) {
582
+ const formatting = createFormatting(state);
583
+ nodes.push(...formatting.nodes);
584
+ edges.push(...formatting.edges);
585
+ }
586
+ if (features.lists ?? true) {
587
+ const lists = createLists(state);
588
+ nodes.push(...lists.nodes);
589
+ edges.push(...lists.edges);
590
+ }
591
+ if (features.blocks ?? true) {
592
+ const blocks = createBlocks(state);
593
+ nodes.push(...blocks.nodes);
594
+ edges.push(...blocks.edges);
595
+ }
596
+ if (customActions) {
597
+ const custom = customActions();
598
+ nodes.push(...custom.nodes);
599
+ edges.push(...custom.edges);
600
+ }
601
+ const editorToolbarGap = createGapSeparator();
602
+ nodes.push(...editorToolbarGap.nodes);
603
+ edges.push(...editorToolbarGap.edges);
604
+ if (features.comment ?? true) {
605
+ const comment = createComment(state);
606
+ nodes.push(...comment.nodes);
607
+ edges.push(...comment.edges);
608
+ }
609
+ if (features.search ?? true) {
610
+ nodes.push(editorToolbarSearch);
611
+ edges.push({
612
+ source: "root",
613
+ target: editorToolbarSearch.id
614
+ });
615
+ }
616
+ if (features.viewMode ?? true) {
617
+ const viewMode = createViewMode(state);
618
+ nodes.push(...viewMode.nodes);
619
+ edges.push(...viewMode.edges);
620
+ }
621
+ return {
622
+ nodes,
623
+ edges
624
+ };
625
+ };
626
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
627
+ const menuCreator = useCallback(() => createToolbar(props), [
628
+ props
629
+ ]);
630
+ const { resolveGroupItems } = useMenuActions(menuCreator);
631
+ return {
632
+ resolveGroupItems,
633
+ onAction
634
+ };
635
+ };
636
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
637
+ const menuProps = useEditorToolbarActionGraph(props);
638
+ return /* @__PURE__ */ React.createElement("div", {
639
+ role: "none",
640
+ className: stackItemContentToolbarClassNames(role)
641
+ }, /* @__PURE__ */ React.createElement(ElevationProvider, {
642
+ elevation: role === "section" ? "positioned" : "base"
643
+ }, /* @__PURE__ */ React.createElement(MenuProvider, {
644
+ ...menuProps,
645
+ attendableId
646
+ }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
647
+ classNames: [
648
+ textBlockWidth,
649
+ "!bg-transparent",
650
+ classNames
651
+ ]
652
+ }))));
653
+ };
657
654
 
658
655
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
659
656
  import { StateField } from "@codemirror/state";
@@ -794,7 +791,7 @@ var clientRectsFor = (dom) => {
794
791
  // packages/ui/react-ui-editor/src/util/react.tsx
795
792
  import React2 from "react";
796
793
  import { createRoot } from "react-dom/client";
797
- import { ThemeProvider } from "@dxos/react-ui";
794
+ import { ThemeProvider, Tooltip } from "@dxos/react-ui";
798
795
  import { defaultTx } from "@dxos/react-ui-theme";
799
796
  var createElement = (tag, options, children) => {
800
797
  const el = document.createElement(tag);
@@ -814,6 +811,11 @@ var renderRoot = (root, node) => {
814
811
  }, node));
815
812
  return root;
816
813
  };
814
+ var createRenderer = (Component) => (el, props) => {
815
+ renderRoot(el, /* @__PURE__ */ React2.createElement(ThemeProvider, {
816
+ tx: defaultTx
817
+ }, /* @__PURE__ */ React2.createElement(Tooltip.Provider, null, /* @__PURE__ */ React2.createElement(Component, props))));
818
+ };
817
819
 
818
820
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
819
821
  var annotationMark = Decoration.mark({
@@ -1857,15 +1859,11 @@ var random = (min, max) => {
1857
1859
  return min + ~~(Math.random() * (max - min + 1));
1858
1860
  };
1859
1861
 
1860
- // packages/ui/react-ui-editor/src/extensions/command/command.ts
1861
- import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
1862
-
1863
- // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1864
- import { RangeSetBuilder } from "@codemirror/state";
1865
- import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1862
+ // packages/ui/react-ui-editor/src/extensions/command/action.ts
1863
+ import { StateEffect as StateEffect2 } from "@codemirror/state";
1866
1864
 
1867
1865
  // packages/ui/react-ui-editor/src/extensions/command/state.ts
1868
- import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
1866
+ import { StateField as StateField3 } from "@codemirror/state";
1869
1867
  import { showTooltip } from "@codemirror/view";
1870
1868
  var commandConfig = singleValueFacet();
1871
1869
  var commandState = StateField3.define({
@@ -1875,8 +1873,8 @@ var commandState = StateField3.define({
1875
1873
  if (effect.is(closeEffect)) {
1876
1874
  return {};
1877
1875
  }
1878
- if (effect.is(openEffect)) {
1879
- const options = tr.state.facet(commandConfig);
1876
+ const { renderDialog } = tr.state.facet(commandConfig);
1877
+ if (effect.is(openEffect) && renderDialog) {
1880
1878
  const { pos, fullWidth } = effect.value;
1881
1879
  const tooltip = {
1882
1880
  pos,
@@ -1884,34 +1882,39 @@ var commandState = StateField3.define({
1884
1882
  arrow: false,
1885
1883
  strictSide: true,
1886
1884
  create: (view) => {
1887
- const dom = document.createElement("div");
1885
+ const root = document.createElement("div");
1888
1886
  const tooltipView = {
1889
- dom,
1887
+ dom: root,
1890
1888
  mount: (view2) => {
1891
1889
  if (fullWidth) {
1892
- const parent = dom.parentElement;
1890
+ const parent = root.parentElement;
1893
1891
  const { paddingLeft, paddingRight } = window.getComputedStyle(parent);
1894
1892
  const widthWithoutPadding = parent.clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight);
1895
- dom.style.width = `${widthWithoutPadding}px`;
1893
+ root.style.width = `${widthWithoutPadding}px`;
1896
1894
  }
1897
- options.onRenderDialog(dom, (action) => {
1898
- view2.dispatch({
1899
- effects: closeEffect.of(null)
1900
- });
1901
- if (action?.insert?.length) {
1902
- const text = action.insert + "\n";
1895
+ renderDialog(root, {
1896
+ onAction: (action) => {
1903
1897
  view2.dispatch({
1904
- changes: {
1905
- from: pos,
1906
- insert: text
1907
- },
1908
- selection: {
1909
- anchor: pos + text.length
1910
- }
1898
+ effects: closeEffect.of(null)
1911
1899
  });
1900
+ switch (action?.type) {
1901
+ case "insert": {
1902
+ const text = action.text + "\n";
1903
+ view2.dispatch({
1904
+ changes: {
1905
+ from: pos,
1906
+ insert: text
1907
+ },
1908
+ selection: {
1909
+ anchor: pos + text.length
1910
+ }
1911
+ });
1912
+ break;
1913
+ }
1914
+ }
1915
+ requestAnimationFrame(() => view2.focus());
1912
1916
  }
1913
- requestAnimationFrame(() => view2.focus());
1914
- });
1917
+ }, view2);
1915
1918
  }
1916
1919
  };
1917
1920
  return tooltipView;
@@ -1928,6 +1931,8 @@ var commandState = StateField3.define({
1928
1931
  showTooltip.from(field, (value) => value.tooltip ?? null)
1929
1932
  ]
1930
1933
  });
1934
+
1935
+ // packages/ui/react-ui-editor/src/extensions/command/action.ts
1931
1936
  var openEffect = StateEffect2.define();
1932
1937
  var closeEffect = StateEffect2.define();
1933
1938
  var openCommand = (view) => {
@@ -1966,7 +1971,38 @@ var commandKeyBindings = [
1966
1971
  }
1967
1972
  ];
1968
1973
 
1974
+ // packages/ui/react-ui-editor/src/extensions/command/command.ts
1975
+ import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1976
+
1969
1977
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1978
+ import { RangeSetBuilder } from "@codemirror/state";
1979
+ import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1980
+ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
1981
+ constructor() {
1982
+ this.deco = Decoration3.none;
1983
+ }
1984
+ update(update2) {
1985
+ const builder = new RangeSetBuilder();
1986
+ const cState = update2.view.state.field(commandState, false);
1987
+ if (!cState?.tooltip) {
1988
+ const selection = update2.view.state.selection.main;
1989
+ const line = update2.view.state.doc.lineAt(selection.from);
1990
+ if (selection.from === selection.to && line.from === line.to) {
1991
+ const hint = onHint();
1992
+ if (hint) {
1993
+ builder.add(selection.from, selection.to, Decoration3.widget({
1994
+ widget: new CommandHint(hint)
1995
+ }));
1996
+ }
1997
+ }
1998
+ }
1999
+ this.deco = builder.finish();
2000
+ }
2001
+ }, {
2002
+ provide: (plugin) => [
2003
+ EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2004
+ ]
2005
+ });
1970
2006
  var CommandHint = class extends WidgetType2 {
1971
2007
  constructor(content) {
1972
2008
  super();
@@ -2006,32 +2042,6 @@ var CommandHint = class extends WidgetType2 {
2006
2042
  return false;
2007
2043
  }
2008
2044
  };
2009
- var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
2010
- constructor() {
2011
- this.deco = Decoration3.none;
2012
- }
2013
- update(update2) {
2014
- const builder = new RangeSetBuilder();
2015
- const cState = update2.view.state.field(commandState, false);
2016
- if (!cState?.tooltip) {
2017
- const selection = update2.view.state.selection.main;
2018
- const line = update2.view.state.doc.lineAt(selection.from);
2019
- if (selection.from === selection.to && line.from === line.to) {
2020
- const hint = onHint();
2021
- if (hint) {
2022
- builder.add(selection.from, selection.to, Decoration3.widget({
2023
- widget: new CommandHint(hint)
2024
- }));
2025
- }
2026
- }
2027
- }
2028
- this.deco = builder.finish();
2029
- }
2030
- }, {
2031
- provide: (plugin) => [
2032
- EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2033
- ]
2034
- });
2035
2045
 
2036
2046
  // packages/ui/react-ui-editor/src/extensions/command/menu.ts
2037
2047
  import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
@@ -2047,11 +2057,11 @@ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2047
2057
  this.button.style.position = "absolute";
2048
2058
  this.button.style.zIndex = "10";
2049
2059
  this.button.style.display = "none";
2050
- options.onRenderMenu(this.button, () => {
2051
- openCommand(view);
2052
- });
2060
+ options.renderMenu(this.button, {
2061
+ onAction: () => openCommand(view)
2062
+ }, view);
2053
2063
  container.appendChild(this.button);
2054
- container.addEventListener("scroll", this.scheduleUpdate);
2064
+ container.addEventListener("scroll", this.scheduleUpdate.bind(this));
2055
2065
  this.scheduleUpdate();
2056
2066
  }
2057
2067
  update(update2) {
@@ -2067,7 +2077,7 @@ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2067
2077
  if (this.rafId != null) {
2068
2078
  cancelAnimationFrame(this.rafId);
2069
2079
  }
2070
- this.rafId = requestAnimationFrame(() => this.updateButtonPosition());
2080
+ this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
2071
2081
  }
2072
2082
  updateButtonPosition() {
2073
2083
  const pos = this.view.state.selection.main.head;
@@ -2097,83 +2107,24 @@ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2097
2107
  }
2098
2108
  });
2099
2109
 
2100
- // packages/ui/react-ui-editor/src/extensions/command/preview.ts
2101
- import { syntaxTree } from "@codemirror/language";
2102
- import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
2103
- import { Decoration as Decoration4, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
2104
- var preview = (options) => {
2105
- return [
2106
- StateField4.define({
2107
- create: (state) => buildDecorations(state, options),
2108
- update: (_, tr) => buildDecorations(tr.state, options),
2109
- // TODO(burdon): Make atomic.
2110
- provide: (field) => EditorView7.decorations.from(field)
2111
- })
2112
- ];
2113
- };
2114
- var buildDecorations = (state, options) => {
2115
- const builder = new RangeSetBuilder2();
2116
- syntaxTree(state).iterate({
2117
- enter: (node) => {
2118
- if (node.name === "Link") {
2119
- const urlNode = node.node.getChild("URL");
2120
- if (urlNode) {
2121
- const text = state.sliceDoc(node.from + 1, urlNode.from - 2);
2122
- const url = state.sliceDoc(urlNode.from, urlNode.to);
2123
- builder.add(node.from, node.to, Decoration4.replace({
2124
- block: true,
2125
- widget: new PreviewWidget(options.onRenderPreview, url, text)
2126
- }));
2127
- }
2128
- }
2129
- }
2130
- });
2131
- return builder.finish();
2132
- };
2133
- var PreviewWidget = class extends WidgetType3 {
2134
- constructor(_onRenderPreview, _url, _text) {
2135
- super();
2136
- this._onRenderPreview = _onRenderPreview;
2137
- this._url = _url;
2138
- this._text = _text;
2139
- }
2140
- eq(other) {
2141
- return this._url === other._url;
2142
- }
2143
- toDOM(view) {
2144
- const root = document.createElement("div");
2145
- root.classList.add("cm-preview");
2146
- this._onRenderPreview(root, {
2147
- url: this._url,
2148
- text: this._text
2149
- });
2150
- return root;
2151
- }
2152
- };
2153
-
2154
2110
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
2155
- var command = (options) => {
2111
+ var command = (options = {}) => {
2156
2112
  return [
2113
+ keymap3.of(commandKeyBindings),
2157
2114
  commandConfig.of(options),
2158
2115
  commandState,
2159
- keymap3.of(commandKeyBindings),
2160
- preview(options),
2161
- floatingMenu(options),
2162
- hintViewPlugin(options),
2163
- EditorView8.focusChangeEffect.of((_, focusing) => {
2116
+ options.renderMenu ? floatingMenu({
2117
+ renderMenu: options.renderMenu
2118
+ }) : [],
2119
+ options.onHint ? hintViewPlugin({
2120
+ onHint: options.onHint
2121
+ }) : [],
2122
+ EditorView7.focusChangeEffect.of((_, focusing) => {
2164
2123
  return focusing ? closeEffect.of(null) : null;
2165
2124
  }),
2166
- EditorView8.theme({
2125
+ EditorView7.theme({
2167
2126
  ".cm-tooltip": {
2168
2127
  background: "transparent"
2169
- },
2170
- ".cm-preview": {
2171
- marginLeft: "-1rem",
2172
- marginRight: "-1rem",
2173
- padding: "1rem",
2174
- borderRadius: "1rem",
2175
- background: "var(--dx-modalSurface)",
2176
- border: "1px solid var(--dx-separator)"
2177
2128
  }
2178
2129
  })
2179
2130
  ];
@@ -2181,8 +2132,8 @@ var command = (options) => {
2181
2132
 
2182
2133
  // packages/ui/react-ui-editor/src/extensions/comments.ts
2183
2134
  import { invertedEffects } from "@codemirror/commands";
2184
- import { StateEffect as StateEffect3, StateField as StateField5 } from "@codemirror/state";
2185
- import { hoverTooltip, keymap as keymap5, Decoration as Decoration5, EditorView as EditorView10, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2135
+ import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
2136
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2186
2137
  import sortBy from "lodash.sortby";
2187
2138
  import { useEffect, useMemo as useMemo2 } from "react";
2188
2139
  import { debounce as debounce2 } from "@dxos/async";
@@ -2191,7 +2142,7 @@ import { isNonNullable } from "@dxos/util";
2191
2142
 
2192
2143
  // packages/ui/react-ui-editor/src/extensions/selection.ts
2193
2144
  import { Transaction } from "@codemirror/state";
2194
- import { EditorView as EditorView9, keymap as keymap4 } from "@codemirror/view";
2145
+ import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
2195
2146
  import { debounce } from "@dxos/async";
2196
2147
  import { invariant as invariant3 } from "@dxos/invariant";
2197
2148
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
@@ -2202,7 +2153,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
2202
2153
  return {
2203
2154
  selection,
2204
2155
  scrollIntoView: !scrollTo,
2205
- effects: scrollTo ? EditorView9.scrollIntoView(scrollTo, {
2156
+ effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
2206
2157
  yMargin: 96
2207
2158
  }) : void 0,
2208
2159
  annotations: Transaction.userEvent.of(stateRestoreAnnotation)
@@ -2244,7 +2195,7 @@ var selectionState = ({ getState, setState } = {}) => {
2244
2195
  // setStateDebounced(id, {});
2245
2196
  // },
2246
2197
  // }),
2247
- EditorView9.updateListener.of(({ view, transactions }) => {
2198
+ EditorView8.updateListener.of(({ view, transactions }) => {
2248
2199
  const id = view.state.facet(documentId);
2249
2200
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
2250
2201
  return;
@@ -2287,7 +2238,7 @@ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src
2287
2238
  var setComments = StateEffect3.define();
2288
2239
  var setSelection = StateEffect3.define();
2289
2240
  var setCommentState = StateEffect3.define();
2290
- var commentsState = StateField5.define({
2241
+ var commentsState = StateField4.define({
2291
2242
  create: (state) => ({
2292
2243
  id: state.facet(documentId),
2293
2244
  comments: [],
@@ -2325,7 +2276,7 @@ var commentsState = StateField5.define({
2325
2276
  return value;
2326
2277
  }
2327
2278
  });
2328
- var styles3 = EditorView10.theme({
2279
+ var styles3 = EditorView9.theme({
2329
2280
  ".cm-comment, .cm-comment-current": {
2330
2281
  margin: "0 -3px",
2331
2282
  padding: "3px",
@@ -2338,14 +2289,14 @@ var styles3 = EditorView10.theme({
2338
2289
  textDecoration: "underline"
2339
2290
  }
2340
2291
  });
2341
- var createCommentMark = (id, isCurrent) => Decoration5.mark({
2292
+ var createCommentMark = (id, isCurrent) => Decoration4.mark({
2342
2293
  class: isCurrent ? "cm-comment-current" : "cm-comment",
2343
2294
  attributes: {
2344
2295
  "data-testid": "cm-comment",
2345
2296
  "data-comment-id": id
2346
2297
  }
2347
2298
  });
2348
- var commentsDecorations = EditorView10.decorations.compute([
2299
+ var commentsDecorations = EditorView9.decorations.compute([
2349
2300
  commentsState
2350
2301
  ], (state) => {
2351
2302
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -2365,10 +2316,10 @@ var commentsDecorations = EditorView10.decorations.compute([
2365
2316
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
2366
2317
  return mark.range(range.from, range.to);
2367
2318
  }).filter(isNonNullable);
2368
- return Decoration5.set(decorations);
2319
+ return Decoration4.set(decorations);
2369
2320
  });
2370
2321
  var commentClickedEffect = StateEffect3.define();
2371
- var handleCommentClick = EditorView10.domEventHandlers({
2322
+ var handleCommentClick = EditorView9.domEventHandlers({
2372
2323
  click: (event, view) => {
2373
2324
  let target = event.target;
2374
2325
  const editorRoot = view.dom;
@@ -2407,7 +2358,7 @@ var trackPastedComments = (onUpdate) => {
2407
2358
  }
2408
2359
  };
2409
2360
  return [
2410
- EditorView10.domEventHandlers({
2361
+ EditorView9.domEventHandlers({
2411
2362
  cut: handleTrack,
2412
2363
  copy: handleTrack
2413
2364
  }),
@@ -2429,7 +2380,7 @@ var trackPastedComments = (onUpdate) => {
2429
2380
  return effects;
2430
2381
  }),
2431
2382
  // Handle paste or the undo of comment deletion.
2432
- EditorView10.updateListener.of((update2) => {
2383
+ EditorView9.updateListener.of((update2) => {
2433
2384
  const restore = [];
2434
2385
  for (let i = 0; i < update2.transactions.length; i++) {
2435
2386
  const tr = update2.transactions[i];
@@ -2540,7 +2491,7 @@ var comments = (options = {}) => {
2540
2491
  // Hover tooltip (for key shortcut hints, etc.)
2541
2492
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
2542
2493
  //
2543
- options.onHover && hoverTooltip((view, pos) => {
2494
+ options.renderTooltip && hoverTooltip((view, pos) => {
2544
2495
  const selection = view.state.selection.main;
2545
2496
  if (selection && pos >= selection.from && pos <= selection.to) {
2546
2497
  return {
@@ -2549,7 +2500,9 @@ var comments = (options = {}) => {
2549
2500
  above: true,
2550
2501
  create: () => {
2551
2502
  const el = document.createElement("div");
2552
- options.onHover(el, shortcut);
2503
+ options.renderTooltip(el, {
2504
+ shortcut
2505
+ }, view);
2553
2506
  return {
2554
2507
  dom: el,
2555
2508
  offset: {
@@ -2569,7 +2522,7 @@ var comments = (options = {}) => {
2569
2522
  //
2570
2523
  // Track deleted ranges and update ranges for decorations.
2571
2524
  //
2572
- EditorView10.updateListener.of(({ view, state, changes }) => {
2525
+ EditorView9.updateListener.of(({ view, state, changes }) => {
2573
2526
  let mod = false;
2574
2527
  const { comments: comments2, ...value } = state.field(commentsState);
2575
2528
  changes.iterChanges((from, to, from2, to2) => {
@@ -2601,7 +2554,7 @@ var comments = (options = {}) => {
2601
2554
  //
2602
2555
  // Track selection/proximity.
2603
2556
  //
2604
- EditorView10.updateListener.of(({ view, state }) => {
2557
+ EditorView9.updateListener.of(({ view, state }) => {
2605
2558
  let min = Infinity;
2606
2559
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2607
2560
  const { head } = state.selection.main;
@@ -2655,7 +2608,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2655
2608
  anchor: range.from
2656
2609
  } : void 0,
2657
2610
  effects: [
2658
- needsScroll ? EditorView10.scrollIntoView(range.from, center ? {
2611
+ needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
2659
2612
  y: "center"
2660
2613
  } : void 0) : [],
2661
2614
  needsSelectionUpdate ? setSelection.of({
@@ -2707,7 +2660,7 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.from
2707
2660
  }
2708
2661
  });
2709
2662
  var useCommentState = (state) => {
2710
- return useMemo2(() => EditorView10.updateListener.of((update2) => {
2663
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2711
2664
  if (update2.docChanged || update2.selectionSet) {
2712
2665
  state.comment = selectionOverlapsComment(update2.state);
2713
2666
  state.selection = hasActiveSelection(update2.state);
@@ -2731,7 +2684,7 @@ var useComments = (view, id, comments2) => {
2731
2684
  });
2732
2685
  };
2733
2686
  var useCommentClickListener = (onCommentClick) => {
2734
- return useMemo2(() => EditorView10.updateListener.of((update2) => {
2687
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2735
2688
  update2.transactions.forEach((transaction) => {
2736
2689
  transaction.effects.forEach((effect) => {
2737
2690
  if (effect.is(commentClickedEffect)) {
@@ -2745,21 +2698,21 @@ var useCommentClickListener = (onCommentClick) => {
2745
2698
  };
2746
2699
 
2747
2700
  // packages/ui/react-ui-editor/src/extensions/debug.ts
2748
- import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2749
- import { StateField as StateField6 } from "@codemirror/state";
2701
+ import { syntaxTree } from "@codemirror/language";
2702
+ import { StateField as StateField5 } from "@codemirror/state";
2750
2703
  var debugNodeLogger = (log8 = console.log) => {
2751
- const logTokens = (state) => syntaxTree2(state).iterate({
2704
+ const logTokens = (state) => syntaxTree(state).iterate({
2752
2705
  enter: (node) => log8(node.type)
2753
2706
  });
2754
- return StateField6.define({
2707
+ return StateField5.define({
2755
2708
  create: (state) => logTokens(state),
2756
2709
  update: (_, tr) => logTokens(tr.state)
2757
2710
  });
2758
2711
  };
2759
2712
 
2760
2713
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
2761
- import { dropCursor, EditorView as EditorView11 } from "@codemirror/view";
2762
- var styles4 = EditorView11.theme({
2714
+ import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
2715
+ var styles4 = EditorView10.theme({
2763
2716
  ".cm-dropCursor": {
2764
2717
  borderLeft: "2px solid var(--dx-accentText)",
2765
2718
  color: "var(--dx-accentText)",
@@ -2773,7 +2726,7 @@ var dropFile = (options = {}) => {
2773
2726
  return [
2774
2727
  styles4,
2775
2728
  dropCursor(),
2776
- EditorView11.domEventHandlers({
2729
+ EditorView10.domEventHandlers({
2777
2730
  drop: (event, view) => {
2778
2731
  event.preventDefault();
2779
2732
  const files = event.dataTransfer?.files;
@@ -2800,7 +2753,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
2800
2753
  import { searchKeymap } from "@codemirror/search";
2801
2754
  import { EditorState } from "@codemirror/state";
2802
2755
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2803
- import { EditorView as EditorView13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2756
+ import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2804
2757
  import defaultsDeep2 from "lodash.defaultsdeep";
2805
2758
  import merge from "lodash.merge";
2806
2759
  import { generateName } from "@dxos/display-name";
@@ -2808,10 +2761,10 @@ import { log as log5 } from "@dxos/log";
2808
2761
  import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2809
2762
 
2810
2763
  // packages/ui/react-ui-editor/src/extensions/focus.ts
2811
- import { StateEffect as StateEffect4, StateField as StateField7 } from "@codemirror/state";
2812
- import { EditorView as EditorView12 } from "@codemirror/view";
2764
+ import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2765
+ import { EditorView as EditorView11 } from "@codemirror/view";
2813
2766
  var focusEffect = StateEffect4.define();
2814
- var focusField = StateField7.define({
2767
+ var focusField = StateField6.define({
2815
2768
  create: () => false,
2816
2769
  update: (value, tr) => {
2817
2770
  for (const effect of tr.effects) {
@@ -2824,7 +2777,7 @@ var focusField = StateField7.define({
2824
2777
  });
2825
2778
  var focus = [
2826
2779
  focusField,
2827
- EditorView12.domEventHandlers({
2780
+ EditorView11.domEventHandlers({
2828
2781
  focus: (event, view) => {
2829
2782
  setTimeout(() => view.dispatch({
2830
2783
  effects: focusEffect.of(true)
@@ -2862,7 +2815,7 @@ var createBasicExtensions = (_props) => {
2862
2815
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2863
2816
  return [
2864
2817
  // NOTE: Doesn't catch errors in keymap functions.
2865
- EditorView13.exceptionSink.of((err) => {
2818
+ EditorView12.exceptionSink.of((err) => {
2866
2819
  log5.catch(err, void 0, {
2867
2820
  F: __dxlog_file8,
2868
2821
  L: 96,
@@ -2877,12 +2830,12 @@ var createBasicExtensions = (_props) => {
2877
2830
  props.drawSelection && drawSelection({
2878
2831
  cursorBlinkRate: 1200
2879
2832
  }),
2880
- props.editable !== void 0 && EditorView13.editable.of(props.editable),
2833
+ props.editable !== void 0 && EditorView12.editable.of(props.editable),
2881
2834
  props.focus && focus,
2882
2835
  props.highlightActiveLine && highlightActiveLine(),
2883
2836
  props.history && history(),
2884
2837
  props.lineNumbers && lineNumbers(),
2885
- props.lineWrapping && EditorView13.lineWrapping,
2838
+ props.lineWrapping && EditorView12.lineWrapping,
2886
2839
  props.placeholder && placeholder(props.placeholder),
2887
2840
  props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2888
2841
  props.scrollPastEnd && scrollPastEnd(),
@@ -2919,14 +2872,14 @@ var defaultThemeSlots = {
2919
2872
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2920
2873
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2921
2874
  return [
2922
- EditorView13.darkTheme.of(themeMode === "dark"),
2923
- EditorView13.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2875
+ EditorView12.darkTheme.of(themeMode === "dark"),
2876
+ EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2924
2877
  // https://github.com/codemirror/theme-one-dark
2925
2878
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2926
- slots.editor?.className && EditorView13.editorAttributes.of({
2879
+ slots.editor?.className && EditorView12.editorAttributes.of({
2927
2880
  class: slots.editor.className
2928
2881
  }),
2929
- slots.content?.className && EditorView13.contentAttributes.of({
2882
+ slots.content?.className && EditorView12.contentAttributes.of({
2930
2883
  class: slots.content.className
2931
2884
  })
2932
2885
  ].filter(isNotFalsy3);
@@ -2955,7 +2908,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2955
2908
 
2956
2909
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2957
2910
  import { codeFolding, foldGutter } from "@codemirror/language";
2958
- import { EditorView as EditorView14 } from "@codemirror/view";
2911
+ import { EditorView as EditorView13 } from "@codemirror/view";
2959
2912
  import React3 from "react";
2960
2913
  import { Icon } from "@dxos/react-ui";
2961
2914
  var folding = (_props = {}) => [
@@ -2970,7 +2923,7 @@ var folding = (_props = {}) => [
2970
2923
  className: "flex h-full items-center"
2971
2924
  });
2972
2925
  return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
2973
- icon: "ph--caret-right--regular",
2926
+ icon: "ph--caret-right--bold",
2974
2927
  size: 3,
2975
2928
  classNames: [
2976
2929
  "mx-3 cursor-pointer",
@@ -2979,7 +2932,7 @@ var folding = (_props = {}) => [
2979
2932
  }));
2980
2933
  }
2981
2934
  }),
2982
- EditorView14.theme({
2935
+ EditorView13.theme({
2983
2936
  ".cm-foldGutter": {
2984
2937
  opacity: 0.3,
2985
2938
  transition: "opacity 0.3s",
@@ -2992,14 +2945,14 @@ var folding = (_props = {}) => [
2992
2945
  ];
2993
2946
 
2994
2947
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2995
- import { EditorView as EditorView15 } from "@codemirror/view";
2948
+ import { EditorView as EditorView14 } from "@codemirror/view";
2996
2949
  var listener = ({ onFocus, onChange }) => {
2997
2950
  const extensions = [];
2998
- onFocus && extensions.push(EditorView15.focusChangeEffect.of((_, focusing) => {
2951
+ onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
2999
2952
  onFocus(focusing);
3000
2953
  return null;
3001
2954
  }));
3002
- onChange && extensions.push(EditorView15.updateListener.of((update2) => {
2955
+ onChange && extensions.push(EditorView14.updateListener.of((update2) => {
3003
2956
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
3004
2957
  }));
3005
2958
  return extensions;
@@ -3007,9 +2960,9 @@ var listener = ({ onFocus, onChange }) => {
3007
2960
 
3008
2961
  // packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
3009
2962
  import { snippet } from "@codemirror/autocomplete";
3010
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
2963
+ import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3011
2964
  import { EditorSelection } from "@codemirror/state";
3012
- import { EditorView as EditorView16, keymap as keymap7 } from "@codemirror/view";
2965
+ import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
3013
2966
  import { useMemo as useMemo3 } from "react";
3014
2967
  var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
3015
2968
  var Inline;
@@ -3032,7 +2985,7 @@ var setHeading = (level) => {
3032
2985
  let prevBlock = -1;
3033
2986
  for (const range of ranges) {
3034
2987
  let sawBlock = false;
3035
- syntaxTree3(state).iterate({
2988
+ syntaxTree2(state).iterate({
3036
2989
  from: range.from,
3037
2990
  to: range.to,
3038
2991
  enter: (node) => {
@@ -3141,7 +3094,7 @@ var setStyle = (type, enable) => {
3141
3094
  let startCovered = false;
3142
3095
  let endCovered = false;
3143
3096
  let { from, to } = range;
3144
- syntaxTree3(state).iterate({
3097
+ syntaxTree2(state).iterate({
3145
3098
  from,
3146
3099
  to,
3147
3100
  enter: (node) => {
@@ -3344,7 +3297,7 @@ var insertTable = (view) => {
3344
3297
  snippets.table(view, null, from, from);
3345
3298
  };
3346
3299
  var removeLinkInner = (from, to, changes, state) => {
3347
- syntaxTree3(state).iterate({
3300
+ syntaxTree2(state).iterate({
3348
3301
  from,
3349
3302
  to,
3350
3303
  enter: (node) => {
@@ -3389,7 +3342,7 @@ var addLink = ({ url, image: image2 } = {}) => {
3389
3342
  let { from, to } = range;
3390
3343
  const cutStyles = [];
3391
3344
  let okay = null;
3392
- syntaxTree3(state).iterate({
3345
+ syntaxTree2(state).iterate({
3393
3346
  from,
3394
3347
  to,
3395
3348
  enter: (node) => {
@@ -3484,7 +3437,7 @@ var addList = (type) => {
3484
3437
  let parentColumn = null;
3485
3438
  const blocks = [];
3486
3439
  for (const { from, to } of state.selection.ranges) {
3487
- syntaxTree3(state).iterate({
3440
+ syntaxTree2(state).iterate({
3488
3441
  from,
3489
3442
  to,
3490
3443
  enter: (node) => {
@@ -3619,7 +3572,7 @@ var removeList = (type) => {
3619
3572
  const stack = [];
3620
3573
  const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
3621
3574
  for (const { from, to } of state.selection.ranges) {
3622
- syntaxTree3(state).iterate({
3575
+ syntaxTree2(state).iterate({
3623
3576
  from,
3624
3577
  to,
3625
3578
  enter: (node) => {
@@ -3706,7 +3659,7 @@ var setBlockquote = (enable) => {
3706
3659
  let lastBlock = -1;
3707
3660
  for (const { from, to } of state.selection.ranges) {
3708
3661
  const sawBlock = false;
3709
- syntaxTree3(state).iterate({
3662
+ syntaxTree2(state).iterate({
3710
3663
  from,
3711
3664
  to,
3712
3665
  enter: (node) => {
@@ -3796,7 +3749,7 @@ var addCodeblock = (target) => {
3796
3749
  for (const { from, to } of selection.ranges) {
3797
3750
  let blockFrom = from;
3798
3751
  let blockTo = to;
3799
- syntaxTree3(state).iterate({
3752
+ syntaxTree2(state).iterate({
3800
3753
  from,
3801
3754
  to,
3802
3755
  enter: (node) => {
@@ -3847,7 +3800,7 @@ var removeCodeblock = ({ state, dispatch }) => {
3847
3800
  let lastBlock = -1;
3848
3801
  const changes = [];
3849
3802
  for (const { from, to } of state.selection.ranges) {
3850
- syntaxTree3(state).iterate({
3803
+ syntaxTree2(state).iterate({
3851
3804
  from,
3852
3805
  to,
3853
3806
  enter: (node) => {
@@ -4009,7 +3962,7 @@ var getFormatting = (state) => {
4009
3962
  }
4010
3963
  }
4011
3964
  }
4012
- syntaxTree3(state).iterate({
3965
+ syntaxTree2(state).iterate({
4013
3966
  from: range.from,
4014
3967
  to: range.to,
4015
3968
  enter: (node) => {
@@ -4098,7 +4051,7 @@ var getFormatting = (state) => {
4098
4051
  };
4099
4052
  };
4100
4053
  var useFormattingState = (state) => {
4101
- return useMemo3(() => EditorView16.updateListener.of((update2) => {
4054
+ return useMemo3(() => EditorView15.updateListener.of((update2) => {
4102
4055
  if (update2.docChanged || update2.selectionSet) {
4103
4056
  Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4104
4057
  state[key] = active;
@@ -4381,9 +4334,9 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
4381
4334
  };
4382
4335
 
4383
4336
  // packages/ui/react-ui-editor/src/extensions/markdown/debug.ts
4384
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4385
- import { StateField as StateField8 } from "@codemirror/state";
4386
- var debugTree = (cb) => StateField8.define({
4337
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
4338
+ import { StateField as StateField7 } from "@codemirror/state";
4339
+ var debugTree = (cb) => StateField7.define({
4387
4340
  create: (state) => cb(convertTreeToJson(state)),
4388
4341
  update: (value, tr) => cb(convertTreeToJson(tr.state))
4389
4342
  });
@@ -4404,24 +4357,24 @@ var convertTreeToJson = (state) => {
4404
4357
  }
4405
4358
  return node;
4406
4359
  };
4407
- return treeToJson(syntaxTree4(state).cursor());
4360
+ return treeToJson(syntaxTree3(state).cursor());
4408
4361
  };
4409
4362
 
4410
4363
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
4411
- import { syntaxTree as syntaxTree8 } from "@codemirror/language";
4412
- import { RangeSetBuilder as RangeSetBuilder4, StateEffect as StateEffect5 } from "@codemirror/state";
4413
- import { EditorView as EditorView20, Decoration as Decoration8, WidgetType as WidgetType6, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
4364
+ import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4365
+ import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
4366
+ import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
4414
4367
  import { invariant as invariant4 } from "@dxos/invariant";
4415
- import { mx as mx4 } from "@dxos/react-ui-theme";
4368
+ import { mx as mx3 } from "@dxos/react-ui-theme";
4416
4369
 
4417
4370
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
4418
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4371
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4419
4372
  import { Transaction as Transaction2 } from "@codemirror/state";
4420
4373
  import { ViewPlugin as ViewPlugin6 } from "@codemirror/view";
4421
4374
  var adjustChanges = () => {
4422
4375
  return ViewPlugin6.fromClass(class {
4423
4376
  update(update2) {
4424
- const tree = syntaxTree5(update2.state);
4377
+ const tree = syntaxTree4(update2.state);
4425
4378
  const adjustments = [];
4426
4379
  for (const tr of update2.transactions) {
4427
4380
  const event = tr.annotation(Transaction2.userEvent);
@@ -4559,14 +4512,14 @@ var getValidUrl = (str) => {
4559
4512
  };
4560
4513
 
4561
4514
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
4562
- import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4563
- import { StateField as StateField9 } from "@codemirror/state";
4564
- import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4515
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4516
+ import { StateField as StateField8 } from "@codemirror/state";
4517
+ import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
4565
4518
  var image = (_options = {}) => {
4566
4519
  return [
4567
- StateField9.define({
4520
+ StateField8.define({
4568
4521
  create: (state) => {
4569
- return Decoration6.set(buildDecorations2(0, state.doc.length, state));
4522
+ return Decoration5.set(buildDecorations(0, state.doc.length, state));
4570
4523
  },
4571
4524
  update: (value, tr) => {
4572
4525
  if (!tr.docChanged && !tr.selection) {
@@ -4586,25 +4539,17 @@ var image = (_options = {}) => {
4586
4539
  filterFrom: from,
4587
4540
  filterTo: to,
4588
4541
  filter: () => false,
4589
- add: buildDecorations2(from, to, tr.state)
4542
+ add: buildDecorations(from, to, tr.state)
4590
4543
  });
4591
4544
  },
4592
- provide: (field) => EditorView17.decorations.from(field)
4545
+ provide: (field) => EditorView16.decorations.from(field)
4593
4546
  })
4594
4547
  ];
4595
4548
  };
4596
- var preloaded = /* @__PURE__ */ new Set();
4597
- var preloadImage = (url) => {
4598
- if (!preloaded.has(url)) {
4599
- const img = document.createElement("img");
4600
- img.src = url;
4601
- preloaded.add(url);
4602
- }
4603
- };
4604
- var buildDecorations2 = (from, to, state) => {
4549
+ var buildDecorations = (from, to, state) => {
4605
4550
  const decorations = [];
4606
4551
  const cursor = state.selection.main.head;
4607
- syntaxTree6(state).iterate({
4552
+ syntaxTree5(state).iterate({
4608
4553
  enter: (node) => {
4609
4554
  if (node.name === "Image") {
4610
4555
  const urlNode = node.node.getChild("URL");
@@ -4615,7 +4560,7 @@ var buildDecorations2 = (from, to, state) => {
4615
4560
  return;
4616
4561
  }
4617
4562
  preloadImage(url);
4618
- decorations.push(Decoration6.replace({
4563
+ decorations.push(Decoration5.replace({
4619
4564
  block: true,
4620
4565
  widget: new ImageWidget(url)
4621
4566
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4627,7 +4572,15 @@ var buildDecorations2 = (from, to, state) => {
4627
4572
  });
4628
4573
  return decorations;
4629
4574
  };
4630
- var ImageWidget = class extends WidgetType4 {
4575
+ var preloaded = /* @__PURE__ */ new Set();
4576
+ var preloadImage = (url) => {
4577
+ if (!preloaded.has(url)) {
4578
+ const img = document.createElement("img");
4579
+ img.src = url;
4580
+ preloaded.add(url);
4581
+ }
4582
+ };
4583
+ var ImageWidget = class extends WidgetType3 {
4631
4584
  constructor(_url) {
4632
4585
  super();
4633
4586
  this._url = _url;
@@ -4649,10 +4602,10 @@ var ImageWidget = class extends WidgetType4 {
4649
4602
  };
4650
4603
 
4651
4604
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4652
- import { EditorView as EditorView18 } from "@codemirror/view";
4605
+ import { EditorView as EditorView17 } from "@codemirror/view";
4653
4606
  var bulletListIndentationWidth = 24;
4654
4607
  var orderedListIndentationWidth = 36;
4655
- var formattingStyles = EditorView18.theme({
4608
+ var formattingStyles = EditorView17.theme({
4656
4609
  /**
4657
4610
  * Horizontal rule.
4658
4611
  */
@@ -4771,18 +4724,18 @@ var formattingStyles = EditorView18.theme({
4771
4724
  });
4772
4725
 
4773
4726
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4774
- import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4775
- import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField10 } from "@codemirror/state";
4776
- import { Decoration as Decoration7, EditorView as EditorView19, WidgetType as WidgetType5 } from "@codemirror/view";
4727
+ import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4728
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4729
+ import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
4777
4730
  var table = (options = {}) => {
4778
- return StateField10.define({
4731
+ return StateField9.define({
4779
4732
  create: (state) => update(state, options),
4780
4733
  update: (_, tr) => update(tr.state, options),
4781
- provide: (field) => EditorView19.decorations.from(field)
4734
+ provide: (field) => EditorView18.decorations.from(field)
4782
4735
  });
4783
4736
  };
4784
4737
  var update = (state, _options) => {
4785
- const builder = new RangeSetBuilder3();
4738
+ const builder = new RangeSetBuilder2();
4786
4739
  const cursor = state.selection.main.head;
4787
4740
  const tables = [];
4788
4741
  const getTable = () => tables[tables.length - 1];
@@ -4790,7 +4743,7 @@ var update = (state, _options) => {
4790
4743
  const table2 = getTable();
4791
4744
  return table2.rows?.[table2.rows.length - 1];
4792
4745
  };
4793
- syntaxTree7(state).iterate({
4746
+ syntaxTree6(state).iterate({
4794
4747
  enter: (node) => {
4795
4748
  switch (node.name) {
4796
4749
  case "Table": {
@@ -4823,19 +4776,19 @@ var update = (state, _options) => {
4823
4776
  tables.forEach((table2) => {
4824
4777
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4825
4778
  if (replace) {
4826
- builder.add(table2.from, table2.to, Decoration7.replace({
4779
+ builder.add(table2.from, table2.to, Decoration6.replace({
4827
4780
  block: true,
4828
4781
  widget: new TableWidget(table2)
4829
4782
  }));
4830
4783
  } else {
4831
- builder.add(table2.from, table2.to, Decoration7.mark({
4784
+ builder.add(table2.from, table2.to, Decoration6.mark({
4832
4785
  class: "cm-table"
4833
4786
  }));
4834
4787
  }
4835
4788
  });
4836
4789
  return builder.finish();
4837
4790
  };
4838
- var TableWidget = class extends WidgetType5 {
4791
+ var TableWidget = class extends WidgetType4 {
4839
4792
  constructor(_table) {
4840
4793
  super();
4841
4794
  this._table = _table;
@@ -4877,14 +4830,14 @@ var Unicode = {
4877
4830
  bulletSmall: "\u2219",
4878
4831
  bulletSquare: "\u2B1D"
4879
4832
  };
4880
- var HorizontalRuleWidget = class extends WidgetType6 {
4833
+ var HorizontalRuleWidget = class extends WidgetType5 {
4881
4834
  toDOM() {
4882
4835
  const el = document.createElement("span");
4883
4836
  el.className = "cm-hr";
4884
4837
  return el;
4885
4838
  }
4886
4839
  };
4887
- var LinkButton = class extends WidgetType6 {
4840
+ var LinkButton = class extends WidgetType5 {
4888
4841
  constructor(url, render) {
4889
4842
  super();
4890
4843
  this.url = url;
@@ -4896,11 +4849,13 @@ var LinkButton = class extends WidgetType6 {
4896
4849
  // TODO(burdon): Create icon and link directly without react?
4897
4850
  toDOM(view) {
4898
4851
  const el = document.createElement("span");
4899
- this.render(el, this.url);
4852
+ this.render(el, {
4853
+ url: this.url
4854
+ }, view);
4900
4855
  return el;
4901
4856
  }
4902
4857
  };
4903
- var CheckboxWidget = class extends WidgetType6 {
4858
+ var CheckboxWidget = class extends WidgetType5 {
4904
4859
  constructor(_checked) {
4905
4860
  super();
4906
4861
  this._checked = _checked;
@@ -4945,7 +4900,7 @@ var CheckboxWidget = class extends WidgetType6 {
4945
4900
  return false;
4946
4901
  }
4947
4902
  };
4948
- var TextWidget = class extends WidgetType6 {
4903
+ var TextWidget = class extends WidgetType5 {
4949
4904
  constructor(text, className) {
4950
4905
  super();
4951
4906
  this.text = text;
@@ -4960,29 +4915,29 @@ var TextWidget = class extends WidgetType6 {
4960
4915
  return el;
4961
4916
  }
4962
4917
  };
4963
- var hide = Decoration8.replace({});
4964
- var blockQuote = Decoration8.line({
4965
- class: mx4("cm-blockquote")
4918
+ var hide = Decoration7.replace({});
4919
+ var blockQuote = Decoration7.line({
4920
+ class: mx3("cm-blockquote")
4966
4921
  });
4967
- var fencedCodeLine = Decoration8.line({
4968
- class: mx4("cm-code cm-codeblock-line")
4922
+ var fencedCodeLine = Decoration7.line({
4923
+ class: mx3("cm-code cm-codeblock-line")
4969
4924
  });
4970
- var fencedCodeLineFirst = Decoration8.line({
4971
- class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
4925
+ var fencedCodeLineFirst = Decoration7.line({
4926
+ class: mx3("cm-code cm-codeblock-line", "cm-codeblock-first")
4972
4927
  });
4973
- var fencedCodeLineLast = Decoration8.line({
4974
- class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
4928
+ var fencedCodeLineLast = Decoration7.line({
4929
+ class: mx3("cm-code cm-codeblock-line", "cm-codeblock-last")
4975
4930
  });
4976
4931
  var commentBlockLine = fencedCodeLine;
4977
4932
  var commentBlockLineFirst = fencedCodeLineFirst;
4978
4933
  var commentBlockLineLast = fencedCodeLineLast;
4979
- var horizontalRule = Decoration8.replace({
4934
+ var horizontalRule = Decoration7.replace({
4980
4935
  widget: new HorizontalRuleWidget()
4981
4936
  });
4982
- var checkedTask = Decoration8.replace({
4937
+ var checkedTask = Decoration7.replace({
4983
4938
  widget: new CheckboxWidget(true)
4984
4939
  });
4985
- var uncheckedTask = Decoration8.replace({
4940
+ var uncheckedTask = Decoration7.replace({
4986
4941
  widget: new CheckboxWidget(false)
4987
4942
  });
4988
4943
  var editingRange = (state, range, focus2) => {
@@ -4997,15 +4952,15 @@ var autoHideTags = /* @__PURE__ */ new Set([
4997
4952
  "SubscriptMark",
4998
4953
  "SuperscriptMark"
4999
4954
  ]);
5000
- var buildDecorations3 = (view, options, focus2) => {
5001
- const deco = new RangeSetBuilder4();
5002
- const atomicDeco = new RangeSetBuilder4();
4955
+ var buildDecorations2 = (view, options, focus2) => {
4956
+ const deco = new RangeSetBuilder3();
4957
+ const atomicDeco = new RangeSetBuilder3();
5003
4958
  const { state } = view;
5004
4959
  const headerLevels = [];
5005
4960
  const getHeaderLevels = (node, level) => {
5006
4961
  invariant4(level > 0, void 0, {
5007
4962
  F: __dxlog_file9,
5008
- L: 178,
4963
+ L: 179,
5009
4964
  S: void 0,
5010
4965
  A: [
5011
4966
  "level > 0",
@@ -5044,7 +4999,7 @@ var buildDecorations3 = (view, options, focus2) => {
5044
4999
  const getCurrentListLevel = () => {
5045
5000
  invariant4(listLevels.length, void 0, {
5046
5001
  F: __dxlog_file9,
5047
- L: 200,
5002
+ L: 201,
5048
5003
  S: void 0,
5049
5004
  A: [
5050
5005
  "listLevels.length",
@@ -5086,7 +5041,7 @@ var buildDecorations3 = (view, options, focus2) => {
5086
5041
  } else {
5087
5042
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
5088
5043
  if (num.length) {
5089
- atomicDeco.add(mark.from, mark.from + len, Decoration8.replace({
5044
+ atomicDeco.add(mark.from, mark.from + len, Decoration7.replace({
5090
5045
  widget: new TextWidget(num, theme.heading(level))
5091
5046
  }));
5092
5047
  }
@@ -5111,7 +5066,7 @@ var buildDecorations3 = (view, options, focus2) => {
5111
5066
  if (node.from === line.to - 1) {
5112
5067
  return false;
5113
5068
  }
5114
- deco.add(line.from, line.from, Decoration8.line({
5069
+ deco.add(line.from, line.from, Decoration7.line({
5115
5070
  class: "cm-list-item",
5116
5071
  attributes: {
5117
5072
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -5128,7 +5083,7 @@ var buildDecorations3 = (view, options, focus2) => {
5128
5083
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
5129
5084
  const line = state.doc.lineAt(node.from);
5130
5085
  const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
5131
- atomicDeco.add(line.from, to, Decoration8.replace({
5086
+ atomicDeco.add(line.from, to, Decoration7.replace({
5132
5087
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
5133
5088
  }));
5134
5089
  break;
@@ -5215,7 +5170,7 @@ var buildDecorations3 = (view, options, focus2) => {
5215
5170
  if (!editing) {
5216
5171
  atomicDeco.add(node.from, marks[0].to, hide);
5217
5172
  }
5218
- deco.add(marks[0].to, marks[1].from, Decoration8.mark({
5173
+ deco.add(marks[0].to, marks[1].from, Decoration7.mark({
5219
5174
  tagName: "a",
5220
5175
  attributes: {
5221
5176
  class: "cm-link",
@@ -5225,7 +5180,7 @@ var buildDecorations3 = (view, options, focus2) => {
5225
5180
  }
5226
5181
  }));
5227
5182
  if (!editing) {
5228
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration8.replace({
5183
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration7.replace({
5229
5184
  widget: new LinkButton(url, options.renderLinkButton)
5230
5185
  }) : hide);
5231
5186
  }
@@ -5259,7 +5214,7 @@ var buildDecorations3 = (view, options, focus2) => {
5259
5214
  }
5260
5215
  }
5261
5216
  };
5262
- const tree = syntaxTree8(state);
5217
+ const tree = syntaxTree7(state);
5263
5218
  if (options.numberedHeadings?.from === void 0) {
5264
5219
  for (const { from, to } of view.visibleRanges) {
5265
5220
  tree.iterate({
@@ -5285,11 +5240,11 @@ var decorateMarkdown = (options = {}) => {
5285
5240
  return [
5286
5241
  ViewPlugin7.fromClass(class {
5287
5242
  constructor(view) {
5288
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations3(view, options, view.hasFocus));
5243
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5289
5244
  }
5290
5245
  update(update2) {
5291
5246
  if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
5292
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations3(update2.view, options, update2.view.hasFocus));
5247
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
5293
5248
  this.clearUpdate();
5294
5249
  } else if (update2.selectionSet) {
5295
5250
  this.scheduleUpdate(update2.view);
@@ -5315,9 +5270,9 @@ var decorateMarkdown = (options = {}) => {
5315
5270
  }
5316
5271
  }, {
5317
5272
  provide: (plugin) => [
5318
- EditorView20.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration8.none),
5319
- EditorView20.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration8.none),
5320
- EditorView20.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration8.none)
5273
+ EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5274
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5275
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
5321
5276
  ]
5322
5277
  }),
5323
5278
  image(),
@@ -5328,12 +5283,12 @@ var decorateMarkdown = (options = {}) => {
5328
5283
  };
5329
5284
 
5330
5285
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
5331
- import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5286
+ import { syntaxTree as syntaxTree8 } from "@codemirror/language";
5332
5287
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
5333
5288
  import { tooltipContent } from "@dxos/react-ui-theme";
5334
- var linkTooltip = (render) => {
5289
+ var linkTooltip = (renderTooltip) => {
5335
5290
  return hoverTooltip2((view, pos, side) => {
5336
- const syntax = syntaxTree9(view.state).resolveInner(pos, side);
5291
+ const syntax = syntaxTree8(view.state).resolveInner(pos, side);
5337
5292
  let link = null;
5338
5293
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
5339
5294
  link = node.name === "Link" ? node : null;
@@ -5346,11 +5301,14 @@ var linkTooltip = (render) => {
5346
5301
  return {
5347
5302
  pos: link.from,
5348
5303
  end: link.to,
5349
- above: true,
5304
+ // NOTE: Forcing above causes the tooltip to flicker.
5305
+ // above: true,
5350
5306
  create: () => {
5351
5307
  const el = document.createElement("div");
5352
- el.className = tooltipContent({}, "pli-2 plb-1");
5353
- render(el, urlText);
5308
+ el.className = tooltipContent({});
5309
+ renderTooltip(el, {
5310
+ url: urlText
5311
+ }, view);
5354
5312
  return {
5355
5313
  dom: el,
5356
5314
  offset: {
@@ -5360,6 +5318,9 @@ var linkTooltip = (render) => {
5360
5318
  };
5361
5319
  }
5362
5320
  };
5321
+ }, {
5322
+ // NOTE: 0 = default of 300ms.
5323
+ hoverTime: 1
5363
5324
  });
5364
5325
  };
5365
5326
 
@@ -5447,6 +5408,165 @@ var InputModeExtensions = {
5447
5408
  ]
5448
5409
  };
5449
5410
 
5411
+ // packages/ui/react-ui-editor/src/extensions/preview/preview.ts
5412
+ import "@dxos/lit-ui/dx-ref-tag.pcss";
5413
+ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5414
+ import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField10 } from "@codemirror/state";
5415
+ import { Decoration as Decoration8, EditorView as EditorView20, WidgetType as WidgetType6 } from "@codemirror/view";
5416
+ var preview = (options = {}) => {
5417
+ return [
5418
+ // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
5419
+ // "Block decorations may not be specified via plugins"
5420
+ StateField10.define({
5421
+ create: (state) => buildDecorations3(state, options),
5422
+ update: (_, tr) => buildDecorations3(tr.state, options),
5423
+ provide: (field) => [
5424
+ EditorView20.decorations.from(field),
5425
+ EditorView20.atomicRanges.of((view) => view.state.field(field))
5426
+ ]
5427
+ }),
5428
+ EditorView20.theme({
5429
+ ".cm-preview-block": {
5430
+ marginLeft: "-1rem",
5431
+ marginRight: "-1rem",
5432
+ padding: "1rem",
5433
+ borderRadius: "0.5rem",
5434
+ background: "var(--dx-modalSurface)",
5435
+ border: "1px solid var(--dx-separator)"
5436
+ }
5437
+ })
5438
+ ];
5439
+ };
5440
+ var getLinkRef = (state, node) => {
5441
+ const mark = node.getChild("LinkMark");
5442
+ const label = node.getChild("LinkLabel");
5443
+ if (mark && label) {
5444
+ const ref = state.sliceDoc(label.from + 1, label.to - 1);
5445
+ return {
5446
+ suggest: ref.startsWith("?"),
5447
+ block: state.sliceDoc(mark.from, mark.from + 1) === "!",
5448
+ label: state.sliceDoc(mark.to, label.from - 1),
5449
+ ref: ref.startsWith("?") ? ref.slice(1) : ref
5450
+ };
5451
+ }
5452
+ };
5453
+ var buildDecorations3 = (state, options) => {
5454
+ const builder = new RangeSetBuilder4();
5455
+ syntaxTree9(state).iterate({
5456
+ enter: (node) => {
5457
+ switch (node.name) {
5458
+ //
5459
+ // Decoration.
5460
+ // [Label][dxn:echo:123]
5461
+ //
5462
+ case "Link": {
5463
+ const link = getLinkRef(state, node.node);
5464
+ if (link) {
5465
+ builder.add(node.from, node.to, Decoration8.replace({
5466
+ widget: new PreviewInlineWidget(options, link)
5467
+ }));
5468
+ }
5469
+ break;
5470
+ }
5471
+ //
5472
+ // Block widget.
5473
+ // ![Label][dxn:echo:123]
5474
+ //
5475
+ case "Image": {
5476
+ const link = getLinkRef(state, node.node);
5477
+ if (options.renderBlock && link) {
5478
+ builder.add(node.from, node.to, Decoration8.replace({
5479
+ block: true,
5480
+ // atomic: true,
5481
+ widget: new PreviewBlockWidget(options, link)
5482
+ }));
5483
+ }
5484
+ break;
5485
+ }
5486
+ }
5487
+ }
5488
+ });
5489
+ return builder.finish();
5490
+ };
5491
+ var PreviewInlineWidget = class extends WidgetType6 {
5492
+ constructor(_options, _link) {
5493
+ super();
5494
+ this._options = _options;
5495
+ this._link = _link;
5496
+ }
5497
+ // override ignoreEvent() {
5498
+ // return false;
5499
+ // }
5500
+ eq(other) {
5501
+ return this._link.ref === other._link.ref && this._link.label === other._link.label;
5502
+ }
5503
+ toDOM(view) {
5504
+ const root = document.createElement("dx-ref-tag");
5505
+ root.setAttribute("label", this._link.label);
5506
+ root.setAttribute("ref", this._link.ref);
5507
+ return root;
5508
+ }
5509
+ };
5510
+ var PreviewBlockWidget = class extends WidgetType6 {
5511
+ constructor(_options, _link) {
5512
+ super();
5513
+ this._options = _options;
5514
+ this._link = _link;
5515
+ }
5516
+ // override ignoreEvent() {
5517
+ // return true;
5518
+ // }
5519
+ eq(other) {
5520
+ return this._link.ref === other._link.ref;
5521
+ }
5522
+ toDOM(view) {
5523
+ const root = document.createElement("div");
5524
+ root.classList.add("cm-preview-block");
5525
+ const handleAction = (action) => {
5526
+ const pos = view.posAtDOM(root);
5527
+ const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
5528
+ if (!node) {
5529
+ return;
5530
+ }
5531
+ const link = getLinkRef(view.state, node);
5532
+ if (link?.ref !== action.link.ref) {
5533
+ return;
5534
+ }
5535
+ switch (action.type) {
5536
+ // TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
5537
+ // Insert ref text.
5538
+ case "insert": {
5539
+ view.dispatch({
5540
+ changes: {
5541
+ from: node.from,
5542
+ to: node.to,
5543
+ insert: action.target.text
5544
+ }
5545
+ });
5546
+ break;
5547
+ }
5548
+ // Remove ref.
5549
+ case "delete": {
5550
+ view.dispatch({
5551
+ changes: {
5552
+ from: node.from,
5553
+ to: node.to
5554
+ }
5555
+ });
5556
+ break;
5557
+ }
5558
+ }
5559
+ };
5560
+ this._options.renderBlock(root, {
5561
+ readonly: view.state.readOnly,
5562
+ link: this._link,
5563
+ onAction: handleAction,
5564
+ onLookup: this._options.onLookup
5565
+ }, view);
5566
+ return root;
5567
+ }
5568
+ };
5569
+
5450
5570
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
5451
5571
  import { keymap as keymap10 } from "@codemirror/view";
5452
5572
  var defaultItems = [
@@ -5522,7 +5642,7 @@ import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5522
5642
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5523
5643
  var instanceCount = 0;
5524
5644
  var useTextEditor = (props = {}, deps = []) => {
5525
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
5645
+ const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
5526
5646
  const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
5527
5647
  const [view, setView] = useState();
5528
5648
  const parentRef = useRef(null);
@@ -5535,7 +5655,7 @@ var useTextEditor = (props = {}, deps = []) => {
5535
5655
  doc: initialValue?.length ?? 0
5536
5656
  }, {
5537
5657
  F: __dxlog_file11,
5538
- L: 75,
5658
+ L: 76,
5539
5659
  S: void 0,
5540
5660
  C: (f, a) => f(...a)
5541
5661
  });
@@ -5552,7 +5672,7 @@ var useTextEditor = (props = {}, deps = []) => {
5552
5672
  };
5553
5673
  }
5554
5674
  const state = EditorState2.create({
5555
- doc: initialValue,
5675
+ doc: doc ?? initialValue,
5556
5676
  // selection: initialSelection,
5557
5677
  extensions: [
5558
5678
  id && documentId.of(id),
@@ -5561,7 +5681,7 @@ var useTextEditor = (props = {}, deps = []) => {
5561
5681
  EditorView21.exceptionSink.of((err) => {
5562
5682
  log7.catch(err, void 0, {
5563
5683
  F: __dxlog_file11,
5564
- L: 97,
5684
+ L: 98,
5565
5685
  S: void 0,
5566
5686
  C: (f, a) => f(...a)
5567
5687
  });
@@ -5593,7 +5713,7 @@ var useTextEditor = (props = {}, deps = []) => {
5593
5713
  id
5594
5714
  }, {
5595
5715
  F: __dxlog_file11,
5596
- L: 134,
5716
+ L: 135,
5597
5717
  S: void 0,
5598
5718
  C: (f, a) => f(...a)
5599
5719
  });
@@ -5610,7 +5730,7 @@ var useTextEditor = (props = {}, deps = []) => {
5610
5730
  selection
5611
5731
  }, {
5612
5732
  F: __dxlog_file11,
5613
- L: 143,
5733
+ L: 144,
5614
5734
  S: void 0,
5615
5735
  C: (f, a) => f(...a)
5616
5736
  });
@@ -5692,7 +5812,10 @@ export {
5692
5812
  blast,
5693
5813
  callbackWrapper,
5694
5814
  clientRectsFor,
5815
+ closeCommand,
5816
+ closeEffect,
5695
5817
  command,
5818
+ commandKeyBindings,
5696
5819
  comments,
5697
5820
  commentsState,
5698
5821
  convertTreeToJson,
@@ -5706,6 +5829,7 @@ export {
5706
5829
  createElement,
5707
5830
  createExternalCommentSync,
5708
5831
  createMarkdownExtensions,
5832
+ createRenderer,
5709
5833
  createThemeExtensions,
5710
5834
  debugDispatcher,
5711
5835
  debugNodeLogger,
@@ -5719,6 +5843,7 @@ export {
5719
5843
  editorGutter,
5720
5844
  editorInputMode,
5721
5845
  editorMonospace,
5846
+ editorWidth,
5722
5847
  editorWithToolbarLayout,
5723
5848
  flattenRect,
5724
5849
  focus,
@@ -5737,8 +5862,11 @@ export {
5737
5862
  markdownTags,
5738
5863
  markdownTagsExtensions,
5739
5864
  mention,
5865
+ openCommand,
5866
+ openEffect,
5740
5867
  overlap,
5741
5868
  preventNewline,
5869
+ preview,
5742
5870
  processEditorPayload,
5743
5871
  removeBlockquote,
5744
5872
  removeCodeblock,
@@ -5756,7 +5884,7 @@ export {
5756
5884
  setStyle,
5757
5885
  singleValueFacet,
5758
5886
  stackItemContentEditorClassNames,
5759
- stackItemContentToolbarClassNames2 as stackItemContentToolbarClassNames,
5887
+ stackItemContentToolbarClassNames,
5760
5888
  table,
5761
5889
  tags2 as tags,
5762
5890
  textRange,